package sample.Utils;

public class IsInUtils {

    /**
     * 判断鼠标位置是否在fillOval绘制的圆形内
     *
     * @param x 椭圆左上角x坐标(你draw方法中的x参数)
     * @param y 椭圆左上角y坐标(你draw方法中的y参数)
     * @param w 椭圆宽度(你draw方法中的w参数)
     * @param h 椭圆高度(你draw方法中的h参数)
     * @return 如果鼠标在圆内返回true，否则返回false
     */
    public static boolean isPointInCircle(double mouseX,double mouseY,double x, double y, double w, double h) {
        // 计算圆心和半径(对于fillOval参数)
        double centerX = x + w / 2;  // 圆心x坐标
        double centerY = y + h / 2;  // 圆心y坐标
        double radiusX = w / 2;      // x轴半径
        double radiusY = h / 2;      // y轴半径

        // 当radiusX == radiusY时简化为圆形判断
        double normalizedX = (mouseX - centerX) / radiusX;
        double normalizedY = (mouseY - centerY) / radiusY;

        return normalizedX * normalizedX + normalizedY * normalizedY <= 1.0;
    }

    // 判断点是否在线段附近
    public static boolean isPointInLine(double x, double y,double lineStartX,double lineStartY,double lineEndX,double lineEndY) {
        double px = lineStartX, py = lineStartY; // 线的起点
        double qx = lineEndX, qy = lineEndY;     // 线的终点
        double dx = qx - px, dy = qy - py;       // 线向量
        //点(x, y)到线段所在直线的投影在向量上的参数t。这个公式的推导涉及到向量投影的概念
        //如果t < 0，则投影点C在线段AB的延长线上，即在A点之前；如果t > 1，则投影点C在线段BA的延长线上，即在B点之后；如果0 <= t <= 1，则C在线段AB上。
        double t = ((x - px) * dx + (y - py) * dy) / (dx * dx + dy * dy); // 投影参数t
        double nearestX = px + t * dx, nearestY = py + t * dy; // 最近点
        //点到最近点的距离平方，判断是否在5像素内，如果是，则认为点在线段上。
        return Math.pow(x - nearestX, 2) + Math.pow(y - nearestY, 2) <= 25; // 5px阈值平方
    }
}
